﻿angular.module('app')
    .controller('HolidayCtrl', [
        "$scope", "WorkContextSrv", '$timeout', '$rootScope', 'HolidaySrv', '$q', 'ngTableParams', '$filter', 'UserSrv', 'globalConfig', 'helperSrv', function ($scope, workContextSrv, $timeout, $rootScope, holidaySrv, $q, ngTableParams, $filter, userSrv, globalConfig, helperSrv) {
            var currentUser = workContextSrv.getCurrentUser();
            var username = currentUser.userName;
            var previousWindowWidth = jQuery(window).width();
            var canceler;
            function restartCanceler() {
                if (typeof canceler !== 'undefined') {
                    canceler.resolve();
                }
                canceler = $q.defer();
            }


            //set active tab
            $scope.currentTab = "mine";
            //change tab function
            $scope.changeTab = function (tab) {
                $scope.currentTab = tab;
            };
            //check current tab
            $scope.isTab = function (tab) {
                return $scope.currentTab == tab;
            };

            //setup model
            $scope.holiday = {};
            $scope.holiday.onSubmitting = false;
            $scope.holiday.viewUser = false;

            //years
            //var years = [];
            var currentDate = new Date();
            //years.push(currentDate.getFullYear() - 2);
            //years.push(currentDate.getFullYear() - 1);
            //years.push(currentDate.getFullYear());
            //years.push(currentDate.getFullYear() + 1);

            //view other model
            $scope.holiday.viewOther = {
                filter: {
                    name: ''
                },
                onLoadingUser: false,
                userList: [],
                onViewDetail: false,
                selectedUser: '',
                selectedDates: [],
                gotYears: [],
                firstLoad: true
            };

            //setup table
            $scope.userTable = new ngTableParams({
                page: 1,            // show first page
                count: 10,          // count per page
                filter: {
                    //userName: 'M'       // initial filter
                }
            }, {
                counts: [],
                total: $scope.holiday.viewOther.userList.length, // length of data
                getData: function ($defer, params) {
                    // use build-in angular filter
                    params.total($scope.holiday.viewOther.userList.length); // set total for recalc pagination
                    $defer.resolve($scope.holiday.viewOther.userList.slice((params.page() - 1) * params.count(), params.page() * params.count()));
                },
                $scope: { $data: {} }
            });

            //handle 'reloaduserTable' event
            $scope.$on("reloadUserTable", function (e, params) {
                //abort all previous request
                $rootScope.$broadcast("abortPendingRequest");

                if ($scope.holiday.viewOther.filter.name === '') {
                    $scope.holiday.viewOther.onLoadingUser = false;
                    $scope.holiday.viewOther.userList = workContextSrv.getCurrentUser().following;
                    $scope.userTable.reload();
                } else {
                    $scope.holiday.viewOther.onLoadingUser = true;
                    userSrv.searchUser({ nameToSearch: $scope.holiday.viewOther.filter.name }).success(function (dt) {
                        $scope.holiday.viewOther.onLoadingUser = false;
                        $scope.holiday.viewOther.userList = dt;
                        $scope.userTable.reload();
                    });
                }

            });

            //watch user typing name
            $scope.$watch("holiday.viewOther.filter.name", function () {
                $scope.$emit("reloadUserTable");
            });

            //setup submit model
            $scope.holiday.submit = {
                selectedDates: [],
                markedDates: [],
                gotYears: [],
                note: '',
                success: false,
                successMessage: '',
                hasError: false,
                errorMEssage: ''
            };

            //index of year in the list will be loaded
            var currentYearIndex = 1;

            var numerOfDatePicker = [1, 3];

            var validResize = function () {
                if (previousWindowWidth > jQuery(window).width()) {
                    if (previousWindowWidth - jQuery(window).width() > 25) {
                        previousWindowWidth = jQuery(window).width();
                        return true;
                    }
                } else {
                    if (jQuery(window).width() - previousWindowWidth > 25) {
                        previousWindowWidth = jQuery(window).width();
                        return true;
                    }
                }
                return false;
            };

            //re-create calendar fit with window width
            jQuery(window).resize(function () {
                if (validResize()) {
                    clearCalendar();
                    renderCalendar(false);

                    clearCalendar2();
                    renderCalendar2(true);
                }
            });

            function clearCalendar() {
                jQuery("#holiday-calendar").removeClass("hasDatepicker");
                jQuery("#holiday-calendar").html('<i class="fa-2x fa fa-spinner fa-spin" style="position: relative; left: 48%; color: rgb(44, 55, 66);"></i>');
                jQuery("#holiday-calendar").html('');
            }

            function clearCalendar2() {
                jQuery("#other-holiday-calendar").removeClass("hasDatepicker");
                jQuery("#other-holiday-calendar").html('<i class="fa-2x fa fa-spinner fa-spin" style="position: relative; left: 48%; color: rgb(44, 55, 66);"></i>');
                jQuery("#other-holiday-calendar").html('');
            }

            function reRenderCalendar(year) {
                $scope.holiday.submit.gotYears.push(year);
                jQuery("#holiday-calendar").hide();
                jQuery("#holiday-calendar").parent().append('<i class="fa-2x fa fa-spinner fa-spin" style="position: relative; left: 48%; color: rgb(44, 55, 66);"></i>');
                holidaySrv.getUserHolidays(username, year, canceler.promise)
               .success(function (dt) {
                   //add holidays to list
                   angular.forEach(dt, function (data) {
                       angular.forEach(data.holiday, function (date) {
                           //convert server date to date object
                           var dateObject = helperSrv.convertServerDateToDateObject(date);
                           //convert date object to formated date
                           var dateFormated = helperSrv.convertDateObjectToFormatedString(dateObject);
                           $scope.holiday.submit.markedDates.push({ date: dateFormated, note: "datetype-" + getDateStatus(data) });
                       });
                   });
                   //show calendar
                   jQuery("#holiday-calendar").show();
                   jQuery("#holiday-calendar").parent().find('.fa-spinner').remove();
               });
            }

            function getDateStatus(data) {
                if (data.type === 'Public') {
                    return 3;
                }
                return data.status;
            }

            function renderCalendar(disabledAll) {
                if (jQuery(window).width() <= 375) { //mobile portrait - 1 calendar
                    numerOfDatePicker = [1, 1];
                } else if (jQuery(window).width() <= 601) { //mobile landscape,, tablet portrait - 2 calendar
                    numerOfDatePicker = [1, 2];
                }
                else {
                    numerOfDatePicker = [1, 3];
                }
                
                jQuery('#holiday-calendar').multiDatesPicker({
                    dateFormat: globalConfig.dateFormat,
                    //defaultDate:"11/11/2014",
                    addDates: [], //set selected date
                    numberOfMonths: numerOfDatePicker, // rows,columns
                    //addDisabledDates: [today.setDate(1), today.setDate(3)], // disable dates	
                    onSelect: function (date) {
                        $scope.$emit("selectDate", date);
                    },
                    onChangeMonthYear: function (year, month, inst) {

                        var dateObj = new Date(inst.selectedYear, inst.selectedMonth + numerOfDatePicker[1], inst.selectedDay);

                        if ($scope.holiday.submit.gotYears.indexOf(year) === -1) {
                            reRenderCalendar(year);
                        }

                        if ($scope.holiday.submit.gotYears.indexOf(dateObj.getFullYear()) === -1) {
                            reRenderCalendar(dateObj.getFullYear());
                        }

                    },
                    beforeShowDay: function (date) {
                        var show = true;
                        var isWhat = '';
                        var userHolidayClass = '';
                        var toolTip = '';

                        var formatedDate = helperSrv.convertDateObjectToFormatedString(date);
                     
                        //disable Weekends
                        if (date.getDay() == 0 || date.getDay() == 6) {
                            isWhat = 'weekend';
                            show = false;
                        }

                        //old days
                        var toDay = new Date();
                        if (date < toDay.setDate(toDay.getDate() - 1)) {
                            isWhat = 'oldday';
                            show = false;
                        }
                        
                        //highlight user holiday
                        for (var i = 0; i < $scope.holiday.submit.markedDates.length; i++) {
                            if ($scope.holiday.submit.markedDates[i].date === formatedDate) {
                                show = false;
                                isWhat = 'userholiday';
                                userHolidayClass = $scope.holiday.submit.markedDates[i].note;
                                toolTip = $scope.holiday.submit.markedDates[i].note === 'datetype-2' ? 'Approved' :
                                    $scope.holiday.submit.markedDates[i].note === 'datetype-1' ? 'Submitted' :
                                    $scope.holiday.submit.markedDates[i].note === 'datetype-0' ? 'Rejected' :
                                    $scope.holiday.submit.markedDates[i].note === 'datetype-3' ? 'Public' : '';
                            }
                        }

                        

                        var className = isWhat === 'weekend' ? 'weekend-date' : isWhat === 'oldday' ? 'old-date' : isWhat === 'holiday' ? 'holiday-date' : isWhat === 'userholiday' ? userHolidayClass : '';

                        if (disabledAll) {
                            return [false, className, toolTip];
                        }
                        return [show, className, toolTip];
                    }, //disable weekend select and hight light holidays
                    //maxPicks: 2, //maximum dates
                    //pickableRange: 7, // range selectable
                    //adjustRangeToDisabled: true,
                    //mode: 'daysRange', // auto select date range
                    //autoselectRange: [0,5] // range of date 'daysRange' mode
                });
                //console.log($scope.holiday.submit.selectedDates);
                //angular.forEach($scope.holiday.submit.selectedDates, function (value, key) {
                //    //mm-dd-yy
                //    var date = value.replace(/(\d{1,2})-(\d{1,2})-(\d{4})/g, function ($0, $1, $2, $3) { return $3 + "-" + $1 + "-" + $2; });
                //    console.log(new Date(date));
                //    //$('#holiday-calendar').multiDatesPicker('addDates', new Date());
                //});
            }

            function reRenderCalendar2(year) {
                    $scope.holiday.viewOther.gotYears.push(year);
                    jQuery("#other-holiday-calendar").hide();
                    jQuery("#other-holiday-calendar").parent().append('<i class="fa-2x fa fa-spinner fa-spin" style="position: relative; left: 48%; color: rgb(44, 55, 66);"></i>');
                    holidaySrv.getUserHolidays($scope.holiday.viewOther.selectedUser, year, canceler.promise)
                   .success(function (dt) {
                       //add holidays to list
                       angular.forEach(dt, function (data) {
                           angular.forEach(data.holiday, function (date) {
                               //convert server date to date object
                               var dateObject = helperSrv.convertServerDateToDateObject(date);
                               //convert date object to formated date
                               var dateFormated = helperSrv.convertDateObjectToFormatedString(dateObject);
                               $scope.holiday.viewOther.selectedDates.push({ date: dateFormated, note: "datetype-" + getDateStatus(data) });
                           });
                       });
                       //show calendar
                       jQuery("#other-holiday-calendar").show();
                       jQuery("#other-holiday-calendar").parent().find('.fa-spinner').remove();
                   });
                }

            function renderCalendar2(disabledAll) {
                if (jQuery(window).width() <= 375) { //mobile portrait - 1 calendar
                    numerOfDatePicker = [1, 1];
                } else if (jQuery(window).width() <= 601) { //mobile landscape,, tablet portrait - 2 calendar
                    numerOfDatePicker = [1, 2];
                }
                else {
                    numerOfDatePicker = [1, 3];
                }
                
                jQuery('#other-holiday-calendar').multiDatesPicker({
                    dateFormat: globalConfig.dateFormat,
                    //defaultDate:"85-02-19"
                    addDates: [], //set selected date
                    numberOfMonths: numerOfDatePicker, // rows,columns
                    onChangeMonthYear: function (year, month, inst) {
                        if ($scope.holiday.viewOther.gotYears.indexOf(year) === -1) {
                            reRenderCalendar2(year);
                        }

                        var dateObj = new Date(inst.selectedYear, inst.selectedMonth + numerOfDatePicker[1], inst.selectedDay);
                        
                        if ($scope.holiday.viewOther.gotYears.indexOf(dateObj.getFullYear()) === -1) {
                            reRenderCalendar2(dateObj.getFullYear());
                        }
                    },
                    //addDisabledDates: [today.setDate(1), today.setDate(3)], // disable dates	
                    beforeShowDay: function (date) {
                        var show = true;
                        var isWhat = '';
                        var userHolidayClass = '';
                        var toolTip = '';

                        var formatedDate = helperSrv.convertDateObjectToFormatedString(date);

                        //disable Weekends
                        if (date.getDay() == 0 || date.getDay() == 6) {
                            isWhat = 'weekend';
                            show = false;
                        }

                        //highlight user holiday
                        for (var i = 0; i < $scope.holiday.viewOther.selectedDates.length; i++) {
                            // mm/dd/yyyy -? yyyy-mm-dd
                            //var dateObject = $scope.holiday.submit.selectedDates[i].date.replace(/(\d{1,2})\/(\d{1,2})\/(\d{4})/g, function ($0, $1, $2, $3) { return $3 + "/" + $1 + "/" + $2; });
                            if ($scope.holiday.viewOther.selectedDates[i].date === formatedDate) {
                                isWhat = 'userholiday';
                                userHolidayClass = $scope.holiday.viewOther.selectedDates[i].note;
                                toolTip =
                                    $scope.holiday.viewOther.selectedDates[i].note === 'datetype-2' ? 'Approved' :
                                    $scope.holiday.viewOther.selectedDates[i].note === 'datetype-1' ? 'Submitted' :
                                    $scope.holiday.viewOther.selectedDates[i].note === 'datetype-2' ? 'Rejected' :
                                    $scope.holiday.viewOther.selectedDates[i].note === 'datetype-3' ? 'Public' : '';
                            }
                        }

                        var className = isWhat === 'weekend' ? 'weekend-date' : isWhat === 'holiday' ? 'holiday-date' : isWhat === 'userholiday' ? userHolidayClass : '';

                        if (disabledAll) {
                            return [false, className, toolTip];
                        }
                        return [show, className, toolTip];
                    }, //disable weekend select and hight light holidays
                    //maxPicks: 2, //maximum dates
                    //pickableRange: 7, // range selectable
                    //adjustRangeToDisabled: true,
                    //mode: 'daysRange', // auto select date range
                    //autoselectRange: [0,5] // range of date 'daysRange' mode
                });
                //console.log($scope.holiday.submit.selectedDates);
                //angular.forEach($scope.holiday.submit.selectedDates, function (value, key) {
                //    //mm-dd-yy
                //    var date = value.replace(/(\d{1,2})-(\d{1,2})-(\d{4})/g, function ($0, $1, $2, $3) { return $3 + "-" + $1 + "-" + $2; });
                //    console.log(new Date(date));
                //    //$('#holiday-calendar').multiDatesPicker('addDates', new Date());
                //});
            }

            //render calendar
            $timeout(function () {
                //cancel pending request
                restartCanceler();
                //clear calendar
                clearCalendar();
                //get holidays
                $scope.holiday.submit.gotYears.push(new Date().getFullYear());
                var lastDate = new Date(new Date().setMonth(new Date().getMonth() + numerOfDatePicker[1] - 1));
                if ($scope.holiday.submit.gotYears.indexOf(lastDate.getFullYear()) === -1) {
                    $scope.holiday.submit.gotYears.push(lastDate.getFullYear());
                }
                //clear selected dates
                $scope.holiday.submit.markedDates = [];
                firstLoad();
            }, 300);

            //load current user holiday
            function firstLoad() {
                //get holidays
                holidaySrv.getUserHolidays(username, $scope.holiday.submit.gotYears[currentYearIndex - 1], canceler.promise)
                   .success(function (dt) {
                       //add holidays to list
                       angular.forEach(dt, function (data) {
                           angular.forEach(data.holiday, function (date) {
                               //convert server date to date object
                               var dateObject = helperSrv.convertServerDateToDateObject(date);
                               //convert date object to formated date
                               var dateFormated = helperSrv.convertDateObjectToFormatedString(dateObject);
                               $scope.holiday.submit.markedDates.push({ date: dateFormated, note: "datetype-" + getDateStatus(data) });
                           });
                       });

                       if (currentYearIndex == $scope.holiday.submit.gotYears.length) {
                           //render calendar
                           renderCalendar(false);
                           //hide preloading
                           $timeout(function () {
                               $rootScope.$broadcast('hidePreloading');
                           }, 500);
                       } else {
                           currentYearIndex++;
                           firstLoad();
                       }
                   });
            }

            //on select date, add selected date to array
            $scope.$on("selectDate", function (e, params) {
                $scope.$apply(function () {
                    var exist = false;
                    for (var i = 0; i < $scope.holiday.submit.selectedDates.length; i++) {
                        if ($scope.holiday.submit.selectedDates[i].date === params) {
                            $scope.holiday.submit.selectedDates.splice(i, 1);
                            exist = true;
                            break;
                        }
                    }
                    if (!exist) {
                        $scope.holiday.submit.selectedDates.push({ date: params, note: "datetype-2" });
                    }
                });
            });

            //submit holiday
            $scope.submitHoliday = function (submit) {
                //hide message
                $scope.holiday.submit.success = false;
                $scope.holiday.submit.successMessage = '';
                $scope.holiday.submit.hasError = false;
                $scope.holiday.submit.errorMessage = '';
                //if user selected dates
                if ($scope.holiday.submit.selectedDates.length) {
                    //cancel pending request
                    restartCanceler();
                    //declare dates array
                    var dates = [];
                    //add selected date to array
                    angular.forEach($scope.holiday.submit.selectedDates, function (dt) {
                        //convert formated date to date object
                        var dateObject = helperSrv.convertFormatedStringToDateObject(dt.date);
                        //convert date object to server date
                        var serverDate = helperSrv.convertDateObjectToServerDate(dateObject);
                        dates.push(serverDate);
                    });
                    //show loading
                    $scope.holiday.onSubmitting = true;
                    //post request apply holiday
                    holidaySrv.applyHolidays(username, dates, canceler.promise)
                        .success(function (dt) {
                            //if success
                            if (angular.isDefined(dt.holidayId)) {
                                //create holiday workflow data
                                var workflowData = {
                                    params: {
                                        woid: '',
                                        wcode: 'HolidayWf'
                                    },
                                    data: [{
                                        "name": "UserName",
                                        "value": username,
                                        "type": "String"
                                    }, {
                                        "name": "UserNote",
                                        "value": submit.note.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, "<br/>"),
                                        "type": "String"
                                    }, {
                                        "name": "HolidayId",
                                        "value": dt.holidayId,
                                        "type": "String"
                                    }]
                                };
                                //post request start holiday workflow
                                holidaySrv.startHolidayWorkflow(workflowData.data, workflowData.params)
                                    .success(function (dtt, stt) {
                                        //show message
                                        $scope.holiday.submit.success = true;
                                        $scope.holiday.submit.successMessage = 'Your Holidays was submitted';

                                        //mark submitted date to calendar
                                        $scope.holiday.submit.selectedDates.forEach(function (sd) {
                                            $scope.holiday.submit.markedDates.push({ date: sd.date, note: "datetype-1" });
                                        });
                                        
                                        //remove selected date on list
                                        $scope.holiday.submit.selectedDates = [];
                                        //remove notes
                                        $scope.holiday.submit.note = '';
                                        //remove selected date on calendar
                                        $("#holiday-calendar").multiDatesPicker('resetDates', 'picked');
                                        //clear current calendar
                                        //clearCalendar();
                                        //render calendar
                                        //renderCalendar(false);
                                        //hide loading
                                        $scope.holiday.onSubmitting = false;
                                    })
                                    .error(function (dte, stt) {
                                        $scope.holiday.submit.hasError = true;
                                        $scope.holiday.submit.errorMessage = "Cannot start workflow";
                                        $scope.holiday.onSubmitting = false;
                                    });
                            } else {
                                //show error if result dont have holidayId value
                                $scope.holiday.submit.hasError = true;
                                $scope.holiday.submit.errorMessage = dt.message;
                                $scope.holiday.onSubmitting = false;
                            }
                        })
                        .error(function (dter) {
                            //show error
                            $scope.holiday.submit.hasError = true;
                            $scope.holiday.submit.errorMessage = "Cannot Apply holiday";
                            $scope.holiday.onSubmitting = false;
                        });
                } else {
                    $scope.holiday.submit.hasError = true;
                    $scope.holiday.submit.errorMessage = "Please select at least 1 date";
                    $scope.holiday.onSubmitting = false;
                }
            };

            var currentOtherYearIndex = 1;

            //view other user holiday
            $scope.viewUserHoliday = function (user) {
                //set current year
                //$scope.holiday.viewOther.selectedYear = currentDate.getFullYear();
                //hide user list, show user holiday
                $scope.holiday.viewOther.onViewDetail = true;
                //set selected user
                $scope.holiday.viewOther.selectedUser = user.userName;
                //show loading
                $scope.holiday.viewOther.onLoadingUser = true;
                //cancel pending request
                restartCanceler();
                //clear calendar
                clearCalendar2();
                currentOtherYearIndex = 1;
                //remove selected date
                $scope.holiday.viewOther.selectedDates = [];
                $scope.holiday.viewOther.gotYears = [];
                $scope.holiday.viewOther.gotYears.push(new Date().getFullYear());
                var lastDate = new Date(new Date().setMonth(new Date().getMonth() + numerOfDatePicker[1] - 1));
                if ($scope.holiday.viewOther.gotYears.indexOf(lastDate.getFullYear()) === -1) {
                    $scope.holiday.viewOther.gotYears.push(lastDate.getFullYear());
                }
                loadUserHoliday();
            };

            function loadUserHoliday() {
                //get user holidays
                holidaySrv.getUserHolidays($scope.holiday.viewOther.selectedUser, $scope.holiday.viewOther.gotYears[currentOtherYearIndex - 1], canceler.promise)
                    .success(function (dt) {
                        //add holiday to list
                        angular.forEach(dt, function (data) {
                            angular.forEach(data.holiday, function (date) {
                                //convert server date to date object
                                var dateObject = helperSrv.convertServerDateToDateObject(date);
                                //convert date object to formated date
                                var dateFormated = helperSrv.convertDateObjectToFormatedString(dateObject);
                                $scope.holiday.viewOther.selectedDates.push({ date: dateFormated, note: "datetype-" + getDateStatus(data) });
                            });
                        });

                        if (currentOtherYearIndex >= $scope.holiday.viewOther.gotYears.length) {
                            currentOtherYearIndex = 1;
                            //remove first load state
                            $scope.holiday.viewOther.firstLoad = false;
                            //remove loading
                            $scope.holiday.viewOther.onLoadingUser = false;
                            //render calendar
                            renderCalendar2(true);
                        } else {
                            currentOtherYearIndex++;
                            loadUserHoliday();
                        }
                    });
            }

            //back to list
            $scope.backToList = function () {
                currentOtherYearIndex = 1;
                //hide user holiday
                $scope.holiday.viewOther.onViewDetail = false;
                //set selected user to empty
                $scope.holiday.viewOther.selectedUser = '';
                //hide loading
                $scope.holiday.viewOther.onLoadingUser = false;
                //clear calendar
                clearCalendar2();
            };
        }
    ]);